home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / 3dprograms / t3dlib / source / writeim.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  20KB  |  810 lines

  1. /* writeim.c - write an Imagine 2.0 TDDD (3D Data Decription) file
  2.  *           - by traversing the TTDDDLIB database
  3.  *           - written by Glenn M. Lewis - 3/27/92
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include "t3dlib.h"
  9. #ifdef __STDC__
  10. #include <stdlib.h>
  11. #include <strings.h>
  12. #include "writeim_protos.h"
  13. #endif
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16.  
  17. #ifdef AZTEC_C
  18. #include <fcntl.h>
  19. #include <exec/types.h>
  20. #endif
  21.  
  22. static void process_INFO();
  23. static void process_OBJ();
  24. static void process_EXTR();
  25. static void process_DESC();
  26. static void process_ISTG();        /* Imagine staging file */
  27.  
  28. /* Here are a few necessary utilities */
  29.  
  30. static void put_name(world, name, size)
  31. WORLD *world;
  32. register char  *name;
  33. register int size;
  34. {
  35.     while (*name && size) {
  36.         fputc(*name++, world->inp);
  37.         size--;
  38.     }
  39.     while (size--) fputc(0, world->inp);    /* Pad the rest of the string w/ 0 */
  40. }
  41.  
  42. static void put_UBYTE(world, u)
  43. WORLD *world;
  44. UBYTE u;
  45. {
  46.     fputc((char)u, world->inp);
  47. }
  48.  
  49. static void put_UWORD(world, w)
  50. WORLD *world;
  51. UWORD w;
  52. {
  53.     put_UBYTE(world, (UBYTE)(w>>8));
  54.     put_UBYTE(world, (UBYTE)(w&0xFF));
  55. }
  56.  
  57. static void put_ULONG(world, l)
  58. WORLD *world;
  59. ULONG l;
  60. {
  61.     put_UWORD(world, (UWORD)(l>>16));
  62.     put_UWORD(world, (UWORD)(l&0xFFFF));
  63. }
  64.  
  65. static void put_FRACT(world, f)
  66. WORLD *world;
  67. double f;
  68. {
  69.     put_ULONG(world, (ULONG)(f*65536.0));
  70. }
  71.  
  72. static void put_XYZ(world, st)            /* Write a common string */
  73. WORLD *world;
  74. XYZ_st *st;
  75. {
  76.     put_FRACT(world, st->x);
  77.     put_FRACT(world, st->y);
  78.     put_FRACT(world, st->z);
  79. }
  80.  
  81. static void put_RGB(world, st)            /* Write a common string */
  82. WORLD *world;
  83. RGB_st *st;
  84. {
  85.     put_UBYTE(world, 0);    /* PAD */
  86.     put_UBYTE(world, st->r);
  87.     put_UBYTE(world, st->g);
  88.     put_UBYTE(world, st->b);
  89. }
  90.  
  91. static void write_size(world, pos)
  92. WORLD *world;
  93. long pos;
  94. {
  95.     long size;
  96.     long cur = ftell(world->inp);
  97.     size = cur-pos;
  98.     if (size&1) { size++; put_UBYTE(world, (UBYTE)0); }
  99.     fseek(world->inp, pos-4L, 0);
  100.     put_ULONG(world, (ULONG)size);
  101.     fseek(world->inp, cur, 0);
  102. }
  103.  
  104. /********************/
  105. /* The MAIN section */
  106. /********************/
  107.  
  108. int write_TDDD(world, myfile)
  109. WORLD *world;
  110. FILE *myfile;
  111. {
  112.     long pos, pos2;
  113.     OBJECT *obj;
  114.     struct stat statbuf;
  115. #ifdef AMIGA
  116.     int x;
  117. #endif
  118.  
  119.     if (!world || !myfile) return(0);
  120.     world->inp = myfile;
  121.  
  122.     if (world->info || world->object) {
  123.         /* Don't write TDDD if there is nothing to write */
  124.  
  125.         /* Start the IFF TDDD file */
  126.         put_name(world, "FORM", 4);
  127.         put_ULONG(world, 0L);        /* Fill this in later [seek(,4L,0)] */
  128.         pos = ftell(world->inp);    /* Save where this starting position is */
  129.         put_name(world, "TDDD", 4);
  130.  
  131.         if (world->info) process_INFO(world, world->info);
  132.         for (obj = world->object; obj; obj=obj->next) {
  133.             put_name(world, "OBJ ", 4);
  134.             put_ULONG(world, 0L);
  135.             pos2 = ftell(world->inp);    /* Save for later */
  136.             process_OBJ(world, obj);
  137.             write_size(world, pos2);
  138.         }
  139.         write_size(world, pos);
  140.  
  141.     /* All done.  Close up shop. */
  142.         fclose(world->inp);
  143.     }
  144.  
  145. /* Also write the staging file if we have staging information */
  146.     if (!world->istg) return(1);
  147.  
  148.     /* Check is the staging file already exists */
  149.     if (stat("staging", &statbuf)==0) {
  150.         fprintf(stderr, "WARNING: Moving existing 'staging' file to 'staging.bak'.\n");
  151. #ifdef AMIGA
  152.         /* We can only assume this will wait until process completes */
  153.         x = system("copy staging staging.bak");
  154.         if (x != 0) fprintf(stderr, "ERROR:  Staging file copy failed\n");
  155. #else
  156.         system("mv staging staging.bak");
  157.         wait(1);
  158. #endif
  159.     }
  160.  
  161.     if (!(world->inp = fopen("staging", "w"))) {
  162.         fprintf(stderr, "WARNING: Could not open 'staging' file for output.\n");
  163.         fprintf(stderr, "No staging information saved!\n");
  164.         world->inp = myfile;
  165.         return(1);
  166.     }
  167.  
  168.     /* Output the staging file... */
  169.     /* Start the IFF ISTG file */
  170.     put_name(world, "FORM", 4);
  171.     put_ULONG(world, 0L);            /* Fill this in later [seek(,4L,0)] */
  172.     pos = ftell(world->inp);        /* Save where this starting position is */
  173.     put_name(world, "ISTG", 4);
  174.     process_ISTG(world);
  175.     write_size(world, pos);
  176.  
  177.     /* Return the file pointer back to normal... */
  178.     fclose(world->inp);
  179.     world->inp = myfile;
  180.     return(1);
  181. }
  182.  
  183. static void process_INFO(world, info)
  184. WORLD *world;
  185. INFO *info;
  186. {
  187.     register ULONG i;
  188.     long pos;
  189.  
  190.     put_name(world, "INFO", 4);
  191.     put_ULONG(world, 0L);
  192.     pos = ftell(world->inp);    /* Save for later */
  193.  
  194.     for (i=0; i<8; i++)
  195.         if (info->brsh[i][0]) {
  196.             put_name(world, "BRSH", 4);
  197.             put_ULONG(world, 82L);
  198.             put_UWORD(world, (UWORD)i);
  199.             put_name(world, info->brsh[i], 80);
  200.         }
  201.  
  202.     for (i=0; i<8; i++)
  203.         if (info->stnc[i][0]) {
  204.             put_name(world, "STNC", 4);
  205.             put_ULONG(world, 82L);
  206.             put_UWORD(world, (UWORD)i);
  207.             put_name(world, info->stnc[i], 80);
  208.         }
  209.  
  210.     for (i=0; i<8; i++)
  211.         if (info->txtr[i][0]) {
  212.             put_name(world, "TXTR", 4);
  213.             put_ULONG(world, 82L);
  214.             put_UWORD(world, (UWORD)i);
  215.             put_name(world, info->txtr[i], 80);
  216.         }
  217.  
  218.     if (info->otrk[0]) {
  219.         put_name(world, "OTRK", 4);
  220.         put_ULONG(world, 18L);
  221.         put_name(world, info->otrk, 18);
  222.     }
  223.  
  224.     if (info->ambi) {
  225.         put_name(world, "AMBI", 4);
  226.         put_ULONG(world, 4L);
  227.         put_RGB(world, info->ambi);
  228.     }
  229.  
  230.     if (info->obsv) {
  231.         put_name(world, "OBSV", 4);
  232.         put_ULONG(world, 28L);
  233.         put_XYZ(world, &info->obsv->came);
  234.         put_XYZ(world, &info->obsv->rota);
  235.         put_FRACT(world, info->obsv->foca);
  236.     }
  237.  
  238.     if (info->ostr) {
  239.         put_name(world, "OSTR", 4);
  240.         put_ULONG(world, 56L);
  241.         put_name(world, info->ostr->path, 18);
  242.         put_XYZ(world, &info->ostr->tran);
  243.         put_XYZ(world, &info->ostr->rota);
  244.         put_XYZ(world, &info->ostr->scal);
  245.         put_UWORD(world, info->ostr->info);
  246.     }
  247.  
  248.     if (info->fade) {
  249.         put_name(world, "FADE", 4);
  250.         put_ULONG(world, 12L);
  251.         put_FRACT(world, info->fade->at);
  252.         put_FRACT(world, info->fade->by);
  253.         put_RGB(world, &info->fade->to);
  254.     }
  255.  
  256.     if (info->skyc) {
  257.         put_name(world, "SKYC", 4);
  258.         put_ULONG(world, 8L);
  259.         put_RGB(world, &info->skyc->hori);
  260.         put_RGB(world, &info->skyc->zeni);
  261.     }
  262.  
  263.     if (info->glb0) {
  264.         put_name(world, "GLB0", 4);
  265.         put_ULONG(world, 8L);
  266.         for (i=0; i<8; i++)
  267.             put_UBYTE(world, (UBYTE)info->glb0[i]);
  268.     }
  269.     write_size(world, pos);
  270. }
  271.  
  272. static void process_OBJ(world, obj)
  273. WORLD *world;
  274. OBJECT *obj;
  275. {
  276.     OBJECT *o;
  277.  
  278.     if (obj->extr) process_EXTR(world, obj);
  279.     else process_DESC(world, obj);
  280.  
  281.     for (o=obj->child; o; o=o->next)
  282.         process_OBJ(world, o);
  283.  
  284.     put_name(world, "TOBJ", 4);
  285.     put_ULONG(world, 0L);
  286. }
  287.  
  288. static void process_EXTR(world, obj)
  289. WORLD *world;
  290. OBJECT *obj;
  291. {
  292.     long pos;
  293.  
  294.     put_name(world, "EXTR", 4);
  295.     put_ULONG(world, 0L);
  296.     pos = ftell(world->inp);    /* Save for later */
  297.  
  298.     put_name(world, "LOAD", 4);
  299.     put_ULONG(world, 80L);
  300.     put_name(world, obj->extr->filename, 80);
  301.  
  302.     put_name(world, "MTRX", 4);
  303.     put_ULONG(world, 60L);
  304.     put_XYZ(world, &obj->extr->mtrx.tran);
  305.     put_XYZ(world, &obj->extr->mtrx.scal);
  306.     put_XYZ(world, &obj->extr->mtrx.rota1);
  307.     put_XYZ(world, &obj->extr->mtrx.rota2);
  308.     put_XYZ(world, &obj->extr->mtrx.rota3);
  309.  
  310.     write_size(world, pos);
  311. }
  312.  
  313. static void process_DESC(world, obj)
  314. WORLD *world;
  315. OBJECT *obj;
  316. {
  317.     register int i, j;
  318.     register DESC *desc;
  319.     FGRP *fgrp;
  320.     long pos;
  321.  
  322.     if (!obj) return;
  323.     desc = obj->desc;
  324.     if (!desc) return;
  325.  
  326.     put_name(world, "DESC", 4);
  327.     put_ULONG(world, 0L);
  328.     pos = ftell(world->inp);    /* Save for later */
  329.  
  330.     if (desc->name) {
  331.         put_name(world, "NAME", 4);
  332.         put_ULONG(world, 18L);
  333.         put_name(world, desc->name, 18);
  334.     }
  335.  
  336.     if (desc->posi) {
  337.         put_name(world, "POSI", 4);
  338.         put_ULONG(world, 12L);
  339.         put_XYZ(world, desc->posi);
  340.     }
  341.  
  342.     if (desc->size) {
  343.         put_name(world, "SIZE", 4);
  344.         put_ULONG(world, 12L);
  345.         put_XYZ(world, desc->size);
  346.     }
  347.  
  348.     if (desc->colr) {
  349.         put_name(world, "COLR", 4);
  350.         put_ULONG(world, 4L);
  351.         put_RGB(world, desc->colr);
  352.     }
  353.  
  354.     if (desc->refl) {
  355.         put_name(world, "REFL", 4);
  356.         put_ULONG(world, 4L);
  357.         put_RGB(world, desc->refl);
  358.     }
  359.  
  360.     if (desc->tran) {
  361.         put_name(world, "TRAN", 4);
  362.         put_ULONG(world, 4L);
  363.         put_RGB(world, desc->tran);
  364.     }
  365.  
  366.     if (desc->spc1) {
  367.         put_name(world, "SPC1", 4);
  368.         put_ULONG(world, 4L);
  369.         put_RGB(world, desc->spc1);
  370.     }
  371.  
  372.     if (desc->ints) {
  373.         put_name(world, "INTS", 4);
  374.         put_ULONG(world, 4L);
  375.         put_FRACT(world, (*desc->ints));
  376.     }
  377.  
  378.     /* Mandatory field... stuff it, regardless */
  379.     if (desc->shap) {
  380.         put_name(world, "SHAP", 4);
  381.         put_ULONG(world, 4L);
  382.         put_UWORD(world, (UWORD)desc->shap[0]);
  383.         put_UWORD(world, (UWORD)desc->shap[1]);
  384.     } else {
  385.         put_name(world, "SHAP", 4);
  386.         put_ULONG(world, 4L);
  387.         put_UWORD(world, (UWORD)2);
  388.         put_UWORD(world, (UWORD)1);
  389.     }
  390.  
  391.     if (desc->axis) {
  392.         put_name(world, "AXIS", 4);
  393.         put_ULONG(world, 36L);
  394.         put_XYZ(world, &desc->axis->xaxi);
  395.         put_XYZ(world, &desc->axis->yaxi);
  396.         put_XYZ(world, &desc->axis->zaxi);
  397.     }
  398.  
  399.     if (desc->tpar) {
  400.         put_name(world, "TPAR", 4);
  401.         put_ULONG(world, 64L);
  402.         for (i=0; i<16; i++) put_FRACT(world, desc->tpar[i]);
  403.     }
  404.  
  405.     if (desc->surf) {
  406.         put_name(world, "SURF", 4);
  407.         put_ULONG(world, 5L);
  408.         for (i=0; i<5; i++) put_UBYTE(world, desc->surf[i]);
  409.         put_UBYTE(world, (UBYTE)0);    /* To make this chunk even-sized */
  410.     }
  411.  
  412.     if (desc->mttr) {
  413.         put_name(world, "MTTR", 4);
  414.         put_ULONG(world, 2L);
  415.         put_UBYTE(world, desc->mttr->type);
  416.         put_UBYTE(world, (UBYTE)(((int)((desc->mttr->indx-1.0)*100.0))&0xFF));
  417.     }
  418.  
  419.     if (desc->spec) {
  420.         put_name(world, "SPEC", 4);
  421.         put_ULONG(world, 2L);
  422.         put_UBYTE(world, desc->spec[0]);
  423.         put_UBYTE(world, desc->spec[1]);
  424.     }
  425.  
  426.     if (desc->prp0) {
  427.         put_name(world, "PRP0", 4);
  428.         put_ULONG(world, 6L);
  429.         for (i=0; i<6; i++) put_UBYTE(world, desc->prp0[i]);
  430.     }
  431.  
  432.     if (desc->prp1) {
  433.         put_name(world, "PRP1", 4);
  434.         put_ULONG(world, 8L);
  435.         for (i=0; i<8; i++) put_UBYTE(world, desc->prp1[i]);
  436.     }
  437.  
  438.     if (desc->stry) {
  439.         put_name(world, "STRY", 4);
  440.         put_ULONG(world, 56L);
  441.         put_name(world, desc->stry->path, 18);
  442.         put_XYZ(world, &desc->stry->tran);
  443.         put_XYZ(world, &desc->stry->rota);
  444.         put_XYZ(world, &desc->stry->scal);
  445.         put_UWORD(world, desc->stry->info);
  446.     }
  447.  
  448.     if (desc->pcount) {
  449.         put_name(world, "PNTS", 4);
  450.         put_ULONG(world, (ULONG)desc->pcount*12L+2L);
  451.         put_UWORD(world, desc->pcount);
  452.         for (i=0; i<desc->pcount; i++)
  453.             put_XYZ(world, &desc->pnts[i]);
  454.     }
  455.  
  456.     if (desc->ecount) {
  457.         put_name(world, "EDGE", 4);
  458.         put_ULONG(world, (ULONG)desc->ecount*4L+2L);
  459.         put_UWORD(world, desc->ecount);
  460.         for (i=0; i<2*desc->ecount; i++)
  461.             put_UWORD(world, desc->edge[i]);
  462.     }
  463.  
  464.     if (desc->eflg) {
  465.         put_name(world, "EFLG", 4);
  466.         put_ULONG(world, (ULONG)desc->eflg->num+2L);
  467.         put_UWORD(world, desc->eflg->num);
  468.         for (i=0; i<desc->eflg->num; i++)
  469.             put_UBYTE(world, desc->eflg->eflg[i]);
  470.         if (desc->eflg->num&1) put_UBYTE(world, 0);    /* Pad on even boundary */
  471.     }
  472.  
  473.     if (desc->fcount) {
  474.         put_name(world, "FACE", 4);
  475.         put_ULONG(world, (ULONG)desc->fcount*6L+2L);
  476.         put_UWORD(world, desc->fcount);
  477.         for (i=0; i<3*desc->fcount; i++)
  478.             put_UWORD(world, desc->face[i]);
  479.  
  480.         if (desc->clst) {
  481.             put_name(world, "CLST", 4);
  482.             put_ULONG(world, (ULONG)desc->fcount*3L+2L);
  483.             put_UWORD(world, desc->fcount);
  484.             for (i=0; i<3*desc->fcount; i++)
  485.                 put_UBYTE(world, desc->clst[i]);
  486.             if (desc->fcount&1) put_UBYTE(world, 0);    /* Pad to even length */
  487.         }
  488.         if (desc->rlst) {
  489.             put_name(world, "RLST", 4);
  490.             put_ULONG(world, (ULONG)desc->fcount*3L+2L);
  491.             put_UWORD(world, desc->fcount);
  492.             for (i=0; i<3*desc->fcount; i++)
  493.                 put_UBYTE(world, desc->rlst[i]);
  494.             if (desc->fcount&1) put_UBYTE(world, 0);    /* Pad to even length */
  495.         }
  496.         if (desc->tlst) {
  497.             put_name(world, "TLST", 4);
  498.             put_ULONG(world, (ULONG)desc->fcount*3L+2L);
  499.             put_UWORD(world, desc->fcount);
  500.             for (i=0; i<3*desc->fcount; i++)
  501.                 put_UBYTE(world, desc->tlst[i]);
  502.             if (desc->fcount&1) put_UBYTE(world, 0);    /* Pad to even length */
  503.         }
  504.     }
  505.  
  506.     for (fgrp=desc->fgrp; fgrp; fgrp=fgrp->next) {
  507.         put_name(world, "FGRP", 4);
  508.         put_ULONG(world, (ULONG)fgrp->num*2L+2L+18L);
  509.         put_UWORD(world, fgrp->num);
  510.         put_name(world, fgrp->name, 18);
  511.         for (i=0; i<fgrp->num; i++)
  512.             put_UWORD(world, fgrp->face[i]);
  513.     }
  514.  
  515.     for (i=0; i<4; i++) {
  516.         if (!desc->txt2[i]) continue;
  517.         put_name(world, "TXT2", 4);
  518.         j = strlen(desc->txt2[i]->Name);
  519. /* CWC */    j = 144L+17L+j;  /* Oddly enough, an odd number is allowed here */
  520. /* CWC         put_ULONG(world, 94L+18L+j+(1-(j&1)));    original line */
  521. /* CWC */    put_ULONG(world, j);
  522.         put_UWORD(world, desc->txt2[i]->Flags);
  523.         put_XYZ(world, &desc->txt2[i]->TAxis.tran);
  524.         put_XYZ(world, &desc->txt2[i]->TAxis.rota1);
  525.         put_XYZ(world, &desc->txt2[i]->TAxis.rota2);
  526.         put_XYZ(world, &desc->txt2[i]->TAxis.rota3);
  527.         put_XYZ(world, &desc->txt2[i]->TAxis.scal);
  528.         for (j = 0; j < 16; j++) put_FRACT(world, desc->txt2[i]->Params[j]);
  529.         for (j = 0; j < 16; j++) put_UBYTE(world, desc->txt2[i]->PFlags[j]);
  530. /* CWC        put_name(world, desc->txt2[i]->SubName, 18); original line */
  531. /* CWC */    put_name(world, desc->txt2[i]->SubName, 17);  /* Yes, this 
  532.                                                                  is correct! */
  533.         j = strlen(desc->txt2[i]->Name);
  534.         put_UWORD(world, j);
  535.         put_name(world, desc->txt2[i]->Name, j);
  536. /* CWC */       j = j + 144L + 17L;
  537.         if (j&1) put_UBYTE(world, 0);    /* Pad the odd byte */
  538.     }
  539.  
  540.     write_size(world, pos);
  541. }
  542.  
  543. /************************************************************************/
  544. /* New code to write staging file - written by Glenn M. Lewis - 8/11/92 */
  545. /************************************************************************/
  546.  
  547. static void process_OSIZ();
  548. static void process_POSN();
  549. static void process_ALGN();
  550. static void process_PALN();
  551. static void process_TALN();
  552. static void process_PTH2();
  553. static void process_GLB2();
  554. static void process_AXIS();
  555. static void process_LITE();
  556. static void process_FILE();
  557.  
  558. static void process_ISTG(world)
  559. WORLD *world;
  560. {
  561.     register ISTG *istg = world->istg;
  562.     register SOBJ *sobj;
  563.     long pos2;
  564.  
  565.     if (!world->inp) return;    /* File not open */
  566.  
  567.     put_name(world, "MAXF", 4);
  568.     put_ULONG(world, 2L);
  569.     put_UWORD(world, istg->maxf);
  570.  
  571.     /* Sort the SOBJ's first? */
  572.  
  573. /* Here is the main loop: */
  574.     for (sobj=istg->head; sobj; sobj=sobj->next) {
  575.         put_name(world, "SOBJ", 4);
  576.         put_ULONG(world, 0L);
  577.  
  578.         pos2 = ftell(world->inp);    /* Save for later */
  579.  
  580.         put_name(world, "NAME", 4);
  581.         put_ULONG(world, 18L);
  582.         put_name(world, sobj->name, 18);
  583.         put_name(world, "STGF", 4);
  584.         put_ULONG(world, 2L);
  585.         put_UWORD(world, sobj->stgf);
  586.         if (sobj->glb2) process_GLB2(sobj, world);
  587.         if (sobj->file) process_FILE(sobj, world);
  588.         if (sobj->lite) process_LITE(sobj, world);
  589.         if (sobj->axis) process_AXIS(sobj, world);
  590.         if (sobj->posn) process_POSN(sobj, world);
  591.         if (sobj->algn) process_ALGN(sobj, world);
  592.         if (sobj->osiz) process_OSIZ(sobj, world);
  593.         if (sobj->paln) process_PALN(sobj, world);
  594.         if (sobj->taln) process_TALN(sobj, world);
  595.         if (sobj->pth2) process_PTH2(sobj, world);
  596.  
  597.         write_size(world, pos2);
  598.     }
  599.  
  600. /* All done. */
  601. }
  602.  
  603. static void process_OSIZ(sobj, world)
  604. SOBJ *sobj;
  605. WORLD *world;
  606. {
  607.     register OSIZ *osiz;
  608.  
  609.     for (osiz=sobj->osiz; osiz; osiz=osiz->next) {
  610.         put_name(world, "OSIZ", 4);
  611.         put_ULONG(world, 18L);
  612.         put_UWORD(world, osiz->flags);
  613.         put_UWORD(world, osiz->start);
  614.         put_UWORD(world, osiz->stop);
  615.         put_XYZ(world, &osiz->size);
  616.     }
  617. }
  618.  
  619. static void process_POSN(sobj, world)
  620. SOBJ *sobj;
  621. WORLD *world;
  622. {
  623.     register POSN *posn;
  624.  
  625.     for (posn=sobj->posn; posn; posn=posn->next) {
  626.         put_name(world, "POSN", 4);
  627.         put_ULONG(world, 18L);
  628.         put_UWORD(world, posn->flags);
  629.         put_UWORD(world, posn->start);
  630.         put_UWORD(world, posn->stop);
  631.         put_XYZ(world, &posn->posn);
  632.     }
  633. }
  634.  
  635. static void process_ALGN(sobj, world)
  636. SOBJ *sobj;
  637. WORLD *world;
  638. {
  639.     register ALGN *algn;
  640.  
  641.     for (algn=sobj->algn; algn; algn=algn->next) {
  642.         put_name(world, "ALGN", 4);
  643.         put_ULONG(world, 18L);
  644.         put_UWORD(world, algn->flags);
  645.         put_UWORD(world, algn->start);
  646.         put_UWORD(world, algn->stop);
  647.         put_XYZ(world, &algn->algn);
  648.     }
  649. }
  650.  
  651. static void process_PALN(sobj, world)
  652. SOBJ *sobj;
  653. WORLD *world;
  654. {
  655.     register PALN *paln;
  656.  
  657.     for (paln=sobj->paln; paln; paln=paln->next) {
  658.         put_name(world, "PALN", 4);
  659.         put_ULONG(world, 6L);
  660.         put_UWORD(world, paln->flags);
  661.         put_UWORD(world, paln->start);
  662.         put_UWORD(world, paln->stop);
  663.     }
  664. }
  665.  
  666. static void process_TALN(sobj, world)
  667. SOBJ *sobj;
  668. WORLD *world;
  669. {
  670.     register TALN *taln;
  671.     int len;
  672.  
  673.     for (taln=sobj->taln; taln; taln=taln->next) {
  674.         len = strlen(taln->trackobj);
  675.         put_name(world, "TALN", 4);
  676.         put_ULONG(world, (ULONG)16L+(long)len);
  677.         put_UWORD(world, taln->flags);
  678.         put_UWORD(world, taln->start);
  679.         put_UWORD(world, taln->stop);
  680.         put_FRACT(world, taln->initial_y);
  681.         put_FRACT(world, taln->final_y);
  682.         /* BCPL string... byte (length) followed by string, then zero */
  683.         put_UBYTE(world, (UBYTE)len);
  684.         put_name(world, taln->trackobj, len);
  685.         put_UBYTE(world, 0);
  686.         if (len&1) put_UBYTE(world, 0);        /* pad byte */
  687.     }
  688. }
  689.  
  690. static void process_PTH2(sobj, world)
  691. SOBJ *sobj;
  692. WORLD *world;
  693. {
  694.     register PTH2 *pth2;
  695.     int len;
  696.  
  697.     for (pth2=sobj->pth2; pth2; pth2=pth2->next) {
  698.         len = strlen(pth2->path);
  699.         put_name(world, "PTH2", 4);
  700.         put_ULONG(world, (ULONG)24L+len);
  701.         put_UWORD(world, pth2->flags);
  702.         put_UWORD(world, pth2->start);
  703.         put_UWORD(world, pth2->stop);
  704.         put_ULONG(world, pth2->acceleration_frames);
  705.         put_FRACT(world, pth2->start_speed);
  706.         put_ULONG(world, pth2->deacceleration_frames);
  707.         put_FRACT(world, pth2->end_speed);
  708.         /* BCPL string... byte (length) followed by string, then zero */
  709.         put_UBYTE(world, (UBYTE)len);
  710.         put_name(world, pth2->path, len);
  711.         put_UBYTE(world, 0);
  712.         if (len&1) put_UBYTE(world, 0);        /* pad byte */
  713.     }
  714. }
  715.  
  716. static void process_GLB2(sobj, world)
  717. SOBJ *sobj;
  718. WORLD *world;
  719. {
  720.     register GLB2 *glb2;
  721.     int len;
  722.  
  723.     for (glb2=sobj->glb2; glb2; glb2=glb2->next) {
  724.         len = strlen(glb2->globalbrush);
  725.         put_name(world, "GLB2", 4);
  726.         put_ULONG(world, (ULONG)356L+len);
  727.         put_UWORD(world, glb2->flags);
  728.         put_UWORD(world, glb2->start);
  729.         put_UWORD(world, glb2->stop);
  730.         put_ULONG(world, glb2->sky_blending);
  731.         put_FRACT(world, glb2->starfield);
  732.         put_ULONG(world, glb2->transition);
  733.         /* These colors are stored as FRACTs */
  734.         put_XYZ(world, &glb2->ambient);
  735.         put_XYZ(world, &glb2->horizon);
  736.         put_XYZ(world, &glb2->zenith1);
  737.         put_XYZ(world, &glb2->zenith2);
  738.         put_XYZ(world, &glb2->fog_color);
  739.         put_FRACT(world, glb2->fog_bottom);
  740.         put_FRACT(world, glb2->fog_top);
  741.         put_FRACT(world, glb2->fog_length);
  742.         put_ULONG(world, glb2->brush_seq);
  743.         put_ULONG(world, glb2->backdrop_seq);
  744.         put_name(world, glb2->backdrop, 256);        /* Fixed size */
  745.         /* BCPL string... byte (length) followed by string, then zero */
  746.         put_UBYTE(world, (UBYTE)len);
  747.         put_name(world, glb2->globalbrush, len);    /* Var. size */
  748.         put_UBYTE(world, 0);
  749.         if (len&1) put_UBYTE(world, 0);        /* pad byte */
  750.     }
  751. }
  752.  
  753. static void process_AXIS(sobj, world)
  754. SOBJ *sobj;
  755. WORLD *world;
  756. {
  757.     register SAXIS *axis;
  758.  
  759.     for (axis=sobj->axis; axis; axis=axis->next) {
  760.         put_name(world, "AXIS", 4);
  761.         put_ULONG(world, 6L);
  762.         put_UWORD(world, axis->flags);
  763.         put_UWORD(world, axis->start);
  764.         put_UWORD(world, axis->stop);
  765.     }
  766. }
  767.  
  768. static void process_LITE(sobj, world)
  769. SOBJ *sobj;
  770. WORLD *world;
  771. {
  772.     register LITE *lite;
  773.  
  774.     for (lite=sobj->lite; lite; lite=lite->next) {
  775.         put_name(world, "LITE", 4);
  776.         put_ULONG(world, 22L);
  777.         put_UWORD(world, lite->flags);
  778.         put_UWORD(world, lite->start);
  779.         put_UWORD(world, lite->stop);
  780.         /* This color is stored as a FRACT */
  781.         put_XYZ(world, &lite->color);
  782.         put_ULONG(world, lite->transition);
  783.     }
  784. }
  785.  
  786. static void process_FILE(sobj, world)
  787. SOBJ *sobj;
  788. WORLD *world;
  789. {
  790.     register SFILE *file;
  791.     int len;
  792.  
  793.     for (file=sobj->file; file; file=file->next) {
  794.         len = strlen(file->object_description);
  795.         put_name(world, "FILE", 4);
  796.         put_ULONG(world, (ULONG)20L+len-(len&1));
  797.         put_UWORD(world, file->flags);
  798.         put_UWORD(world, file->start);
  799.         put_UWORD(world, file->stop);
  800.         put_FRACT(world, file->cycles_to_perform);
  801.         put_FRACT(world, file->initial_cycle_phase);
  802.         put_ULONG(world, file->transition);
  803.         /* BCPL string... byte (length) followed by string */
  804.         put_UBYTE(world, (UBYTE)len);
  805.         put_name(world, file->object_description, len);
  806.         if (!(len&1)) put_UBYTE(world, 0);        /* pad byte */
  807.     }
  808. }
  809.  
  810.